package org.oimwrapper.connectors.adapters;

import com.thortech.xl.dataaccess.*;
import java.util.*;

import org.oimwrapper.connectors.*;

/**
 * Handles incoming recon events - implements enabling / disabling of resource objects in OIM, and password sync.
 */
public class OIMReconHandler extends OIMAdapterBase {

	/**
	 * Default Constructor
	 *
	 * @param Database This is a reference to the current database connection, as found under <code>Adapter
	 *                 References -&gt; Database Reference</code> in the Adapter Factory.
	 */
	public OIMReconHandler(tcDataProvider Database) {
		super("RECON.HANDLER", Database);
		logger.debug("Entering reconHandler()");
		logger.debug("Exiting reconHandler()");
	}
	
	/**
	 * Sets the recon flag field if present.
	 * 
	 * @param ReconFlagField The process form field in which the 'is recon' flag is stored.
	 * @param ProcessInstanceKey The process instance key of this resource.
	 * @param Set <code>true</code> to set the recon flag, or <code>false</code> to unset the flag.
	 * @exception Exception
	 */
	protected void setReconFlag(String ReconFlagField, long ProcessInstanceKey, boolean Set) throws Exception {
		logger.debug("Entering reconHandler.setReconFlag()");
		if (ReconFlagField != null && ReconFlagField.length() > 0) {
			setProcessFormValue(ProcessInstanceKey, ReconFlagField, Set ? "1" : "0");
		}
		logger.debug("Exiting reconHandler.setReconFlag()");
	}
	
	/**
	 * Updates the access policy flags on this resource.
	 * 
	 * @param ProcessInstanceKey The process instance key of the resource to update.
	 * @exception Exception
	 */
	protected void updatePolicyFlags(long ProcessInstanceKey) throws Exception {
		logger.debug("Entering reconHandler.updatePolicyFlags()");
		OIMPolicyFlagChecker checker = new OIMPolicyFlagChecker(this);
		Map[] instances = checker.getResourceDetails(ProcessInstanceKey);
		for (int i = 0; i < instances.length; i++) {
			checker.processSingleInstance(instances[i]);
		}
		logger.debug("Exiting reconHandler.updatePolicyFlags()");
	}

	/**
	 * Handles the enabling/disabling of resource objects in OIM based on the data retrieved during recon.
	 *
	 * @param ReconFlagField The process form field in which the 'is recon' flag is stored.   Specifying an 
	 *                       empty value will cause setting and unsetting of the recon flag to be skipped.
	 * @param ResourceState <code>Enabled</code> if the resource should be enabled, or <code>Disabled</code>
	 *                      if the resource should be disabled.  Other values will cause the resource state
	 *                      setting to be skipped.
	 * @param ProcessInstanceKey The process instance key of this resource.
	 * @param UserKey The user key of the user who owns this resource.
	 * @param PasswordSyncField The process form field in which the 'is password sync' flag is stored.
	 *                          Specifying an empty value will cause password sync to be skipped.
	 * @param Password The password value for the resource object.
	 * @return <code>SUCCESS</code> if the method succeeds, or <code>FAILURE</code> if the operation fails.   
	 *         Details about any operational failure are logged to the system logger as error messages.
	 */
	public String handleRecon(String ReconFlagField, String ResourceState, long ProcessInstanceKey, long UserKey, String PasswordSyncField, String Password) {
		logger.debug("Entering reconHandler.handleRecon()");
		String result = "FAILURE";
		try {
			setReconFlag(ReconFlagField, ProcessInstanceKey, true);
			try {
				if (ResourceState.equalsIgnoreCase("disabled") || ResourceState.equalsIgnoreCase("true")) {
					long objectInstanceKey = getObjectInstanceKey(ProcessInstanceKey, UserKey);
					disableOimResource(UserKey, objectInstanceKey);
				} else if (ResourceState.equalsIgnoreCase("enabled") || ResourceState.equalsIgnoreCase("false")) {
					long objectInstanceKey = getObjectInstanceKey(ProcessInstanceKey, UserKey);
					enableOimResource(UserKey, objectInstanceKey);
				}
				if (checkIfOimVersion("9.1.0.1861.11")) {
					logger.debug("Skipping policy re-evaluation; not needed on this OIM version.");
				} else {
					updatePolicyFlags(ProcessInstanceKey);
				}
				if (PasswordSyncField != null && PasswordSyncField.length() > 0) {
					String passwordSync = getProcessFormValue(ProcessInstanceKey, PasswordSyncField);
					logger.debug("password-sync: " + passwordSync);
					if (passwordSync.equalsIgnoreCase("true")) {
						logger.info("Setting password on OIM user " + Long.toString(UserKey));
						setOimUserPassword(UserKey, decryptForOim(Password));
						setProcessFormValue(ProcessInstanceKey, PasswordSyncField, "false");
						logger.debug("password-sync flag set back to false");
					}
				}
			} finally {
				setReconFlag(ReconFlagField, ProcessInstanceKey, false);
				result = "SUCCESS";
			}
		} catch (Exception e) {
			OIMExceptionHandler.handleException(logger, e, getClass());
		}
		logger.debug("Exiting reconHandler.handleRecon()");
		return result;
	}
}